/***************************************************
Class: Framework
Includes: stdafx.h, Graphics.h, Input.h, Timer.h
Editors: Gindi
Existing Issues: None
Description: Creates a framework for the application, calls the update, render, 
and handle input in GameApp. Main game loop is in this file.
***************************************************/
#pragma once

#include "stdafx.h"
#include "Graphics.h"
#include "Input.h"
#include "resource.h"
#include "Timer.h"

#define WS_CUSTOMWINDOW		(WS_OVERLAPPED		| \
							WS_CAPTION			| \
                            WS_SYSMENU			| \
                            WS_MINIMIZEBOX)

class BaseApp {
public:
	virtual ~BaseApp() {}
	virtual void Release() = 0;
	virtual void OnCreateDevice(LPDIRECT3DDEVICE9 pDevice) = 0;
	virtual void OnResetDevice(LPDIRECT3DDEVICE9 pDevice) = 0;
	virtual void OnLostDevice() = 0;
	virtual void OnDestroyDevice() = 0;
	virtual void OnUpdateFrame(LPDIRECT3DDEVICE9 pDevice, float elapsedTime) = 0;
	virtual void OnRenderFrame(LPDIRECT3DDEVICE9 pDevice, float elapsedTime) = 0;
	virtual void ProcessInput(long changeInX, long changeInY, long changeInZ, bool* pMouseButtons, bool* pPressedKeys, float elapsedTime, HWND hWnd) = 0;
	virtual void setAA(bool a_AA) = 0;
};


class Framework {
public:
    Framework(BaseApp* pGameApp);
    ~Framework() { Release(); }
    bool Initialize(char* title, HINSTANCE hInstance, int width, int height);
    void Run();
    void Release();
    static LRESULT CALLBACK StaticWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
    void LockKey(DWORD key);
    
	long getXCursor();
    long getYCursor();
    int getWidth();
    int getHeight();
    float getFPS();
	HWND getHandle() { return m_hWnd; }

private:
	LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
	void OnCreateDevice();
	void OnResetDevice();
	void OnLostDevice();
	void OnDestroyDevice();
	void OnUpdateFrame();
	void OnRenderFrame();
	void Pause(bool rendering, bool timer);
	void CheckAndResetLostDevice();

	HWND			m_hWnd;
	HINSTANCE		m_hInstance;
	bool			m_active;
	int				m_windowWidth;
	int				m_windowHeight;
	WINDOWPLACEMENT	m_wp;
	bool			m_renderingPaused;
	bool			m_timerPaused;
	int				m_renderingPauseCount;
	int				m_timerPauseCount;
	bool			m_closing;

	Graphics*		m_pGraphics;
	BaseApp*		m_pGameApp;
	Timer*			m_pTimer;
	InputDevice		m_mouse;
	InputDevice		m_keyboard;
	LPDIRECTINPUT8	m_pDI;
};
